Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

247
Views
Error "Se esperaba que la operación de la base de datos afectara a 1 fila(s) pero en realidad afectó a 0 fila(s)" al agregar una entidad relacionada

He estado buscando una solución para escribir un método de actualización "genérico" en EF Core que actualice todas las propiedades modificadas de una entidad, incluida una colección relacionada. La razón de esto es que almaceno las traducciones del nombre de una entidad en una tabla diferente. Encontré esta solución que parecía funcionar bien al principio, pero luego me di cuenta de que aparece un error "Se esperaba que la operación de la base de datos afectara a 1 fila (s) pero en realidad afectó a 0 fila (s)" cuando lo único que cambié en el entidad estaba agregando una nueva traducción de nombre en la tabla relacionada TblProjectTranslations . Aquí está mi código:

 public async Task UpdateProjectAsync(TblProject updatedEntity) { TblProject dbEntity = Context.TblProjects .Include(dbEntity => dbEntity.TblProjectTranslations) .SingleOrDefault(dbEntity => dbEntity.ProjectId == updatedEntity.ProjectId); if (dbEntity != null) { Context.Entry(dbEntity).CurrentValues.SetValues(updatedEntity); foreach (TblProjectTranslation dbTranslation in dbEntity.TblProjectTranslations.ToList()) { if (!updatedEntity.TblProjectTranslations .Any(translation => translation.ProjectId == dbTranslation.ProjectId && translation.Language == dbTranslation.Language)) { Context.TblProjectTranslations.Remove(dbTranslation); } } foreach (TblProjectTranslation newTranslation in updatedEntity.TblProjectTranslations) { TblProjectTranslation dbTranslation = dbEntity.TblProjectTranslations .SingleOrDefault(dbTranslation => dbTranslation.ProjectId == newTranslation.ProjectId && dbTranslation.Language == newTranslation.Language); if (dbTranslation != null) { Context.Entry(dbTranslation).CurrentValues.SetValues(newTranslation); } else { dbEntity.TblProjectTranslations.Add(newTranslation); } } await Context.SaveChangesAsync(); } }

Estas son las clases de ingeniería inversa de EF Core:

 public partial class TblProject { public TblProject() { TblProjectTranslations = new HashSet<TblProjectTranslation>(); } public int ProjectId { get; set; } public virtual ICollection<TblProjectTranslation> TblProjectTranslations { get; set; } } public partial class TblProjectTranslation { public int ProjectId { get; set; } public string Language { get; set; } public string ProjectName { get; set; } public virtual TblProject Project { get; set; } }

Así es como se definen en OnModelCreating :

 modelBuilder.Entity<TblProject>(entity => { entity.HasKey(e => e.ProjectId); entity.ToTable("TBL_project"); entity.Property(e => e.ProjectId).HasColumnName("project_ID"); }); modelBuilder.Entity<TblProjectTranslation>(entity => { entity.HasKey(e => new { e.ProjectId, e.Language }); entity.ToTable("TBL_project_translation"); entity.HasIndex(e => e.ProjectId, "IX_TBL_project_translation_project_ID"); entity.Property(e => e.ProjectId).HasColumnName("project_ID"); entity.Property(e => e.Language) .HasMaxLength(5) .HasColumnName("language") .HasDefaultValueSql("('-')"); entity.Property(e => e.ProjectName) .IsRequired() .HasMaxLength(50) .HasColumnName("project_name") .HasDefaultValueSql("('-')"); entity.HasOne(d => d.Project) .WithMany(p => p.TblProjectTranslations) .HasForeignKey(d => d.ProjectId) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("TBL_project_translation_TBL_project"); });

Lo que no entiendo es que dbEntity.TblProjectTranslations.Add(newTranslation) parece ser el problema. Cuando reemplazo esta línea con await Context.TblProjectTranslations.AddAsync(newTranslation) , el error "mágicamente" desaparece, pero ¿no se supone que ambas formas deben hacer básicamente lo mismo? Aquí hay un ejemplo de una updatedEntity y una dbEntity de base de datos que capturé mientras depuraba la función justo antes de que ocurriera el problema:

 updatedEntity: ProjectId: 41 TblProjectTranslations: 1 Entry with: Language: "en" Project: null ProjectId: 41 ProjectName: "TestNameEN" dbEntity: ProjectId: 41 TblProjectTranslations: No entries

¿Que esta pasando aqui? Ni siquiera tengo ningún activador en la base de datos en ambas tablas que parecían ser la causa de este error para otras personas.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Después de jugar un poco con el modelo de muestra, el código y las explicaciones, finalmente pude reproducirlo. El culpable parece ser la clave compuesta y el valor predeterminado para la parte de la cadena:

 entity.HasKey(e => new { e.ProjectId, e.Language }); // (1) entity.Property(e => e.Language) .HasMaxLength(5) .HasColumnName("language") .HasDefaultValueSql("('-')"); // (2)

Lo mismo sucede si usas

 .HasDefaultValue("-")

Esta combinación de alguna manera hace que EF considere el elemento agregado a la propiedad de navegación de la colección principal

 dbEntity.TblProjectTranslations.Add(newTranslation);

como Modified en lugar de Added , lo que luego conduce al error en cuestión.

Dado que no puedo encontrar una explicación de dicho comportamiento en la documentación de EF Core y, en general, se ve mal, sugeriría ir e informarlo al rastreador de problemas de EF Core GitHub .

Mientras tanto, las posibles soluciones que veo son

  • Eliminar .HasDefaultValueSql / .HasDefaultValue para la columna de clave

  • En lugar de agregar el elemento secundario a la colección principal, agréguelo directamente al contexto o al DbSet correspondiente (opcionalmente, configure la propiedad de navegación de referencia de antemano "por si acaso"):

 newTranslation.Project = dbEntity; Context.Add(newTranslation);
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!